package com.yanqu.road.dao.impl.config;

import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.impl.TempDao;
import com.yanqu.road.entity.config.patrons.*;
import com.yanqu.road.entity.enums.eCombType;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class PatronsDaoImpl extends TempDao {

	public Map<Integer, PatronsInfo> getPatronsInfoMap() {
		Map<Integer, PatronsInfo> dataMap = new HashMap<>();
		ResultSet rs = null;
		CallableStatement call = null;
		String sql = "select * from t_p_patrons";
		try {
			getDb().setConnName(DbNameStrategy.getConfigDb());
			call = getDb().getConnection().prepareCall(sql);
			rs = call.executeQuery();
			while (rs.next()) {
				PatronsInfo data = new PatronsInfo();
				data.setId(rs.getInt("id"));
				data.setQuality(rs.getInt("quality"));
				data.setQualification(rs.getInt("qualification"));
				data.setOccupation(rs.getInt("occupation"));
				data.setCombId(rs.getInt("combId"));
				data.setCanStage(rs.getBoolean("canStage"));
				List<Integer> oSkillList = StringUtils.stringToIntegerListNoZero(rs.getString("skills"), "\\|");
				//有解锁条件的技能，其他技能达到多少级解锁另外的技能
				List<String> skillInfoStrList = StringUtils.stringToStringList(rs.getString("unlockSkills"), "\\|");
				Map<Integer,Map<Integer,Integer>> skillUnLockMap = new ConcurrentHashMap<>();
				for(String skillInfoStr : skillInfoStrList){
					List<String> skillInfo2StrList = StringUtils.stringToStringList(skillInfoStr, "=");
					if(skillInfo2StrList.size() == 3){
						//条件类型1//10635=1=10639;100 技能id=解锁类型=解锁技能:100
						if(Integer.valueOf(skillInfo2StrList.get(1)) == 1){
							int skillId = Integer.valueOf(skillInfo2StrList.get(0));
							if(!oSkillList.contains(skillId)){
								oSkillList.add(skillId);
							}
							List<Integer> skillInfo2List = StringUtils.stringToIntegerList(skillInfo2StrList.get(2), ";");
							Map<Integer,Integer> skillLevelMap = new ConcurrentHashMap<>();
							skillLevelMap.put(skillInfo2List.get(0),skillInfo2List.get(1));
							skillUnLockMap.put(Integer.valueOf(skillInfo2StrList.get(0)),skillLevelMap);
						}
					}
				}
				data.setKeepsake(rs.getInt("keepsake"));
				data.setSkillList(oSkillList);
				data.setSkillUnLockMap(skillUnLockMap);
                //initUnlockSkillList(data, rs.getString("unlockSkills"));
				data.setTalentList(StringUtils.stringToIntegerListNoZero(rs.getString("talents"), "\\|"));
				data.setInitSkillList(StringUtils.stringToIntegerListNoZero(rs.getString("initSkills"),"\\|"));
				String linkage = rs.getString("linkage");
				if ("0".equals(linkage) || StringUtils.isNullOrEmpty(linkage)) {
					data.setLinkAge(0);
				}else {
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
					Date date = sdf.parse(linkage);
					data.setLinkAge(date.getTime());
				}
				data.setTwins(rs.getInt("isTwins") == 1);
				dataMap.put(data.getId(), data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return dataMap;
	}

	private void initUnlockSkillList(PatronsInfo data, String unlockSkills) {
		if(StringUtils.isNullOrEmpty(unlockSkills) || "0".equals(unlockSkills)){
			return;
		}
		List<String> skillItemParams = StringUtils.stringToStringList(unlockSkills, "\\|");
		for (String itemParam : skillItemParams) {
			List<String> paramsList = StringUtils.stringToStringList(itemParam, "=");
			if(paramsList.size() != 3){
				continue;
			}
			int skillId = Integer.parseInt(paramsList.get(0));
			int unlockType = Integer.parseInt(paramsList.get(1));
			List<Integer> srcParamList = StringUtils.stringToIntegerList(paramsList.get(2), ";");
			if(skillItemParams.size() != 2){
				continue;
			}
			int srcSkill = srcParamList.get(0);
			int limitLv = srcParamList.get(1);
			data.getUnlockSkillList().add(new PatronsUnlockSkill(skillId, unlockType, srcSkill, limitLv));
		}
	}

	public Map<Integer, PatronsUpgradeInfo> getPatronsUpgradeInfoMap() {
		Map<Integer, PatronsUpgradeInfo> dataMap = new HashMap<>();
		ResultSet rs = null;
		CallableStatement call = null;
		String sql = "select * from t_p_patrons_upgrade";
		try {
			getDb().setConnName(DbNameStrategy.getConfigDb());
			call = getDb().getConnection().prepareCall(sql);
			rs = call.executeQuery();
			while (rs.next()) {
				PatronsUpgradeInfo data = new PatronsUpgradeInfo();
				data.setLevel(rs.getInt("level"));
				data.setConsume(PropertyHelper.parseStringToProperty(rs.getString("consume")));
				data.setConsumeNew(PropertyHelper.parseStringToProperty(rs.getString("consumeNew")));

				dataMap.put(data.getLevel(), data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return dataMap;
	}

    public Map<Integer, PatronsBreak> getPatronsBreakMap() {
        Map<Integer, PatronsBreak> dataMap = new HashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select * from t_p_patrons_break";
        try {
            getDb().setConnName(DbNameStrategy.getConfigDb());
            call = getDb().getConnection().prepareCall(sql);
            rs = call.executeQuery();
            while (rs.next()) {
                PatronsBreak data = new PatronsBreak();
                data.setBreakLv(rs.getInt("nums"));
                data.setCurrentMaxLv(rs.getInt("maxLevel"));
                data.setConsume(PropertyHelper.parseStringToProperty(rs.getString("consume")));
                data.setAddQualification(rs.getInt("talentAdd"));

                dataMap.put(data.getBreakLv(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

	public Map<Integer, PatronsStage> getPatronsStageMap() {
		Map<Integer, PatronsStage> dataMap = new HashMap<>();
		ResultSet rs = null;
		CallableStatement call = null;
		String sql = "select * from t_p_patrons_stage";
		try {
			getDb().setConnName(DbNameStrategy.getConfigDb());
			call = getDb().getConnection().prepareCall(sql);
			rs = call.executeQuery();
			while (rs.next()) {
				PatronsStage data = new PatronsStage();
				data.setStageLv(rs.getInt("level"));
				data.setNeedPatronsLv(rs.getInt("needPatronsLevel"));
				data.setConsume(PropertyHelper.parseStringToProperty(rs.getString("consume")));
				data.setAddAbility(rs.getLong("addStrength"));
				data.setAddAbilityAddition(rs.getInt("addStrengthPer"));
				data.setAddSkillId(rs.getInt("addSkillId"));

				dataMap.put(data.getStageLv(), data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return dataMap;
	}

	public Map<Integer, CombInfo> getPatronsCombMap() {
		Map<Integer, CombInfo> dataMap = new HashMap<>();
		ResultSet rs = null;
		CallableStatement call = null;
		String sql = "select * from t_p_patrons_comb";
		try {
			getDb().setConnName(DbNameStrategy.getConfigDb());
			call = getDb().getConnection().prepareCall(sql);
			rs = call.executeQuery();
			while (rs.next()) {
				CombInfo data = parsePatronsComb(rs);
				dataMap.put(data.getId(), data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return dataMap;
	}

	public Map<Integer, CombInfo> getPatronsCombMap(int type) {
		Map<Integer, CombInfo> dataMap = new HashMap<>();
		ResultSet rs = null;
		CallableStatement call = null;
		String sql = "select * from t_p_patrons_comb where type=?";
		try {
			getDb().setConnName(DbNameStrategy.getConfigDb());
			call = getDb().getConnection().prepareCall(sql);
			call.setInt(1, type);
			rs = call.executeQuery();
			while (rs.next()) {
				CombInfo data = parsePatronsComb(rs);
				dataMap.put(data.getId(), data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return dataMap;
	}

	private CombInfo parsePatronsComb(ResultSet rs) throws SQLException {
		CombInfo data = new CombInfo();
		data.setId(rs.getInt("id"));
		String skillStr = rs.getString("skillId");
		List<String> skillInfoList = StringUtils.stringToStringList(skillStr,"\\|");
		if(skillInfoList.size() > 1){
			Map<Integer,Integer> skillMap = new ConcurrentHashMap<>();
			for (String skillInfo : skillInfoList) {
				List<Integer> infoList = StringUtils.stringToIntegerList(skillInfo, "=");
				skillMap.put(infoList.get(0), infoList.get(1));
			}
			data.setPatronsSkill(skillMap);
		} else {
			data.setSkillId(rs.getInt("skillId"));
		}
		Map<Integer, Map<Integer, CombSkillUnlockInfo>> patronsAdvancedSkillMap = getICombSkillUnlockInfoMap(rs);

		data.setAdvancedSkillId(rs.getString("advancedSkillId"));

		data.setPatronsAdvancedSkill(patronsAdvancedSkillMap);

		data.setCombSkillId(rs.getInt("combSkillId"));

		data.setExtra(rs.getString("extra"));

		data.setCombList(StringUtils.stringToIntegerList(data.getExtra(), "\\|"));

		Map<Integer, List<Integer>> skill2Map = new ConcurrentHashMap<>();
		String skillId2Str = rs.getString("skillId2");
		String[] skillStrArray = skillId2Str.split("\\|");
		if (skillStrArray.length > 1) {
			for (String skill2Str : skillStrArray) {
				String[] skillParam = skill2Str.split("=");
				int patronsId = Integer.parseInt(skillParam[0]);
				List<Integer> skillIdList = StringUtils.stringToIntegerList(skillParam[1], ";");
				skill2Map.put(patronsId, skillIdList);
			}
		}
		data.setPatronsSkill2(skill2Map);
		return data;
	}

	public static Map<Integer, Map<Integer, CombSkillUnlockInfo>> getICombSkillUnlockInfoMap(ResultSet rs) throws SQLException {
		if (rs.getInt("type") == eCombType.TravelBook.getValue()) { // 旅行册额外解析
			return new HashMap<>();
		}
		String advancedSkillStr = rs.getString("advancedSkillId");
		List<String> advancedSkillInfoList = StringUtils.stringToStringList(advancedSkillStr, "\\|");
		Map<Integer, Map<Integer, CombSkillUnlockInfo>> patronsAdvancedSkillMap = new ConcurrentHashMap<>();
		for (String advancedSkillInfo : advancedSkillInfoList) {
			Map<Integer, CombSkillUnlockInfo> advancedSkillMap = new ConcurrentHashMap<>();
			if (advancedSkillInfoList.size() == 1) {
				Integer skillId = rs.getInt("advancedSkillId");
				if (0 != skillId) {
					CombSkillUnlockInfo combSkillUnlockInfo = new CombSkillUnlockInfo(skillId);
					advancedSkillMap.put(skillId, combSkillUnlockInfo);
					patronsAdvancedSkillMap.put(0, advancedSkillMap);
				}
				break;
			}
			String[] patronsToSkills = advancedSkillInfo.split("=", 2);
			Integer patronsId = Integer.valueOf(patronsToSkills[0]);

			if (patronsToSkills.length > 1) {
				String[] unlockSkills = patronsToSkills[1].split(";");
				for (String unlockSkillInfo : unlockSkills) {
					String[] advancedSkillParam = unlockSkillInfo.split("#");
					Integer skillId = Integer.valueOf(advancedSkillParam[0]);
					CombSkillUnlockInfo combSkillUnlockInfo = new CombSkillUnlockInfo(skillId);
					if (advancedSkillParam.length > 1) {
						List<Integer> limitParams = StringUtils.stringToIntegerList(advancedSkillParam[1], "=");
						combSkillUnlockInfo.setLimitSkillId(limitParams.get(0));
						combSkillUnlockInfo.setLimitSkillLevel(limitParams.get(1));
					}
					advancedSkillMap.put(skillId, combSkillUnlockInfo);
				}
			}
			patronsAdvancedSkillMap.put(patronsId, advancedSkillMap);
		}
		return patronsAdvancedSkillMap;
	}
}
